var spa_shell = (function() {
    // 变量声明 start
    var configMap = {
            // 定义anchor使用的映射，用于验证
            anchor_schema_map : {
                chat : {open : true, close : true}
            },
            main_html : String() +
            '<div class="spa-shell-head">' +
                '<div class="spa-shell-head-logo"></div>' +
                '<div class="spa-shell-head-acct"></div>' +
                '<div class="spa-shell-head-search"></div>' +
            '</div>' +
            '<div class="spa-shell-main">' +
                '<div class="spa-shell-main-nav"></div>' +
                '<div class="spa-shell-main-content"></div>' +
            '</div>' +
            '<div class="spa-shell-foot"></div>' +
            '<div class="spa-shell-chat"></div>' +
            '<div class="spa-shell-modal"></div>',

            chat_extend_time : 1000,
            chat_extend_height : 450,
            chat_extend_title : 'Click to retract',

            chat_retract_time : 300,
            chat_retract_height : 15,
            chat_retract_title : 'Click to extend',
        },
        stateMap = {
            $container : null,
            anchor_map : {},
            is_chat_retracted : true
        },
        jqueryMap = {},
        copyAnchorMap, setJqueryMap, toggleChat,
        changeAnchorPart, onHashChange,
        initModule, onClickChat;

        copyAnchorMap = function() {
            return $.extend(true, {}, stateMap.anchor_map);
        };
        // 变量声明 End

        // util方法 start
        // 控制Chat显示和隐藏
        toggleChat = function(do_extend, callback) {
            px_chat_ht= jqueryMap.$chat.height();
            is_open = px_chat_ht ===configMap.chat_extend_height;
            is_close = px_chat_ht ===configMap.chat_retract_height;
            is_sliding = !is_open && ! is_close;
            if (is_sliding) return false;

            if (do_extend) {
                jqueryMap.$chat.animate(
                    {height : configMap.chat_extend_height},
                    configMap.chat_extend_time,
                    function() {
                        jqueryMap.$chat.attr('title', configMap.chat_extend_title);
                        stateMap.is_chat_retracted = false;
                        if (callback) {
                            callback(jqueryMap.$chat);
                        }
                    });
                return true;
            }

            jqueryMap.$chat.animate(
                {height : configMap.chat_retract_height},
                configMap.chat_retract_time,
                function() {
                    jqueryMap.$chat.attr('title', configMap.chat_retract_title);
                    stateMap.is_chat_retracted = true;
                    if (callback) {
                        callback(jqueryMap.$chat);
                    }
                }
            );
            return true;
        };
        // util方法 end

        // DOM 操作 start   
        changeAnchorPart = function(arg_map) {
            var anchor_map_revies = copyAnchorMap(),
            bool_return = true,
            key_name, key_name_dep;

            KEYVAL:

            for (key_name in arg_map) {
                if (arg_map.hasOwnProperty(key_name)) {
                    if (key_name.indexOf('_') === 0) {
                        continue KEYVAL;
                    }

                    anchor_map_revies[key_name] = arg_map[key_name];

                    key_name_dep = '_' + key_name;
                    if (arg_map[key_name_dep]) {
                        anchor_map_revies[key_name_dep] = arg_map[key_name_dep];
                    } else {
                        delete anchor_map_revies[key_name_dep];
                        delete anchor_map_revies['_s' + key_name_dep];
                    }
                }
            }
            try {
                $.uriAnchor.setAnchor(anchor_map_revies);
            } catch (error) {
                $.uriAnchor.setAnchor(stateMap.anchor_map_revies, null, true);
                bool_return = false;
            }
            return bool_return;
        };

        // 管理jquery变量Map
        setJqueryMap = function() {
            var $container = stateMap.$container;
            jqueryMap = {
                $container : $container,
                $chat : $container.find('.spa-shell-chat')
            };
        };

        onHashChange = function(event) {
            var anchor_map_previous = copyAnchorMap(),
                anchor_map_proposed,
                _s_chat_previous, _s_chat_proposed,
                s_chat_proposed;
            
            // attamp to parse anchor
            try {
                anchor_map_proposed = $.uriAnchor.makeAnchorMap();
            } catch(error) {
                $.uriAnchor.setAnchor(anchor_map_previous, null, true);
                return false;
            }
            stateMap.anchor_map = anchor_map_proposed;

            // convenience vars
            _s_chat_previous =  anchor_map_previous._s_chat;
            _s_chat_proposed =  anchor_map_proposed._s_chat;

            if (!anchor_map_previous
                || _s_chat_previous !== _s_chat_proposed) {
                s_chat_proposed = anchor_map_proposed.chat;
                switch (s_chat_proposed) {
                    case 'open':
                        toggleChat(true);
                        break;
                    case 'close':
                        toggleChat(false);
                        break;
                    default:
                        toggleChat(false);
                        delete anchor_map_proposed.chat;
                        $.uriAnchor.setAnchor(anchor_map_proposed, null, true);
                        break;
                }
            }
            return false;
        };
        // DOM 操作 end

        // 事件处理 Start
        onClickChat = function(event) {
            changeAnchorPart({
                chat : (stateMap.is_chat_retracted ? 'open' : 'close')
            });
            return false;
            // if (toggleChat(stateMap.is_chat_retracted)) {
            //     $.uriAnchor.setAnchor({
            //         chat : (stateMap.is_chat_retracted ? 'open' : 'closed')
            //     });
            // }
            // return false;
        };
        // 事件处理 End

        // Public 方法 start
        initModule = function($container) {
            stateMap.$container = $container;
            $container.html(configMap.main_html);
            setJqueryMap();

            stateMap.is_chat_retracted = true;
            jqueryMap.$chat.attr('title', configMap.chat_retract_title).click(onClickChat);

            $.uriAnchor.configModule({
                schema_map : configMap.anchor_schema_map
            });

            $(window)
                .bind('hashchange', onHashChange)
                .trigger('hashchange');
        };
        // Public 方法 End

        return {
            initModule : initModule
        }
}());